package com.xtool.livewallpaper.video

import android.content.Context
import android.graphics.Bitmap
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.opengl.GLES30


internal object VideoWallpaperUtils {
    private const val TAG = "Utils"

    /**
     * createVideoThumbnailFromUri
     * @param context Activity context or application context.
     * @param uri Video uri.
     * @return Bitmap thumbnail
     *
     * Hacked from ThumbnailUtils.createVideoThumbnail()'s code.
     */
    fun createVideoThumbnailFromUri(
        context: Context,
        uri: Uri
    ): Bitmap? {
        var bitmap: Bitmap? = null
        val retriever = MediaMetadataRetriever()
        try {
            retriever.setDataSource(context, uri)
            bitmap = retriever.getFrameAtTime(-1)
        } catch (e: IllegalArgumentException) {
            // Assume this is a corrupt video file
            e.printStackTrace()
        } catch (e: RuntimeException) {
            // Assume this is a corrupt video file.
            e.printStackTrace()
        } finally {
            try {
                retriever.release()
            } catch (e: RuntimeException) {
                // Ignore failures while cleaning up.
                e.printStackTrace()
            }
        }
        if (bitmap == null) {
            return null
        }
        // Scale down the bitmap if it's too large.
        val width = bitmap.width
        val height = bitmap.height
        val max = Math.max(width, height)
        if (max > 512) {
            val scale = 512f / max
            val w = Math.round(scale * width)
            val h = Math.round(scale * height)
            bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true)
        }
        return bitmap
    }

    fun compileShaderResourceGLES30(
        shaderType: Int,
        shaderSource: String
    ): Int {
        val shader = GLES30.glCreateShader(shaderType)
        if (shader == 0) {
            throw RuntimeException("Failed to create shader")
        }
        GLES30.glShaderSource(shader, shaderSource)
        GLES30.glCompileShader(shader)
        val status = IntArray(1)
        GLES30.glGetShaderiv(shader, GLES30.GL_COMPILE_STATUS, status, 0)
        if (status[0] == 0) {
            val log = GLES30.glGetShaderInfoLog(shader)
            GLES30.glDeleteShader(shader)
            throw RuntimeException(log)
        }
        return shader
    }

    fun linkProgramGLES30(
        vertShader: Int,
        fragShader: Int
    ): Int {
        val program = GLES30.glCreateProgram()
        if (program == 0) {
            throw RuntimeException("Failed to create program")
        }
        GLES30.glAttachShader(program, vertShader)
        GLES30.glAttachShader(program, fragShader)
        GLES30.glLinkProgram(program)
        val status = IntArray(1)
        GLES30.glGetProgramiv(program, GLES30.GL_LINK_STATUS, status, 0)
        if (status[0] == 0) {
            val log = GLES30.glGetProgramInfoLog(program)
            GLES30.glDeleteProgram(program)
            throw RuntimeException(log)
        }
        return program
    }
}